/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"


#include "InputBuffer.h"
#include "KeyConverter.h"

#include <iostream>

/**
=============================
Constructor -
=============================
*/
InputBuffer::InputBuffer()
{
    m_carrot = m_top = 0;
    m_active = false;
    m_upperCase = false;
    m_CapitolLocks  = false;
    m_sBuffer.clear();
}

/**
=============================
Deconstructor
=============================
*/
InputBuffer::~InputBuffer()
{

}

/**
=============================
Retrieve the string to this buffer
=============================
*/
std::string InputBuffer::GetBuffer()
{
    return m_sBuffer;
}

/*
=================
Set a new buffer
=================
*/
void  InputBuffer::SetBuffer(const std::string &newBuffer)
{
	m_sBuffer = newBuffer;
	m_carrot = m_top = m_sBuffer.length();
}

/*
================
Get the current carrot pos
================
*/
int   InputBuffer::GetCarrotPos()
{
    return m_carrot;
}

/**
=================
Clear the buffer
=================
*/
void    InputBuffer::Clear() 
{
    m_sBuffer.clear();
    m_carrot = m_top = 0;
}

/*
===============
Append a char to the buffer
===============
*/
#define SPACE 32
void  InputBuffer::Append(char c)
{
    if ( m_top < BUFFER_SIZE-1 )
    {
        // account for spaces
        if ( c == SPACE ) {
            m_sBuffer.insert(m_carrot," ");
        } else {
            std::string temp(1, c);
            m_sBuffer.insert(m_carrot, temp);
        }
        m_carrot++;
        m_top++;
    }
}

/*
================
Process this key
================
*/
void InputBuffer::ProcessKey(bool down, int key )
{
    if ( !down )
    {
        switch( key )
        {        
        case MK_LSHIFT:
        case MK_RSHIFT:
            m_upperCase = down;
        break;
        default: return;
        }
    }

    switch( key )
    {
    case MK_HOME:
        m_carrot = 0;
        break;
    case MK_END:
        m_carrot = m_top;
        break;
    case MK_CAPSLOCK:
        m_CapitolLocks = !m_CapitolLocks;
        break;
    case MK_BACKSPACE:
        m_carrot--;
        if ( m_carrot < 0 ) {
            m_carrot = 0;
            return;
        }
        m_sBuffer.erase(m_carrot,1);
        m_top--;
        break;
    case MK_DELETE:
        if(m_carrot < m_top)
		{   // delete that char
            if ( m_carrot >= 0 ) {
                m_sBuffer.erase(m_carrot, 1);
			    m_top--;
            }
		}
        break;
    case MK_RIGHT:
        m_carrot++;
        if ( m_carrot >= m_top )
            m_carrot = m_top;
        break;
    case MK_LEFT:
        m_carrot--;
        if ( m_carrot < 0 )
            m_carrot = 0;
        break;
    case MK_LSHIFT:
    case MK_RSHIFT:
        m_upperCase = down;
        break;
    default:
        if ( m_carrot < BUFFER_SIZE )
        {
            KeyConverter convert;
            if ( key > 31 && key < 127 ) 
            {
                if ( key == 32 )
                    Append( (char)32 );
                else if ( m_CapitolLocks )
                {
                    if ( ( (key >= 65 && key <= 90) || (key >= 97 && key <= 122) ) && !m_upperCase )   // is a letter
                        Append ( convert.GetShiftValue( key ) );
                    else if ( m_upperCase && !( (key >= 65 && key <= 90) || (key >= 97 && key <= 122) ) ) 
                    {
                        Append( convert.GetShiftValue( key ) );
                    } else
                        Append( key );
                }
                else if ( m_upperCase  )
                    Append ( convert.GetShiftValue( key ) );
                else
                    Append( key );
            }
        }
    }
    
}

/**
========================
Test to see if this buffer is
active
========================
*/
bool  InputBuffer::IsActive()
{
    return m_active;
}

/**
========================
Set the active status of this 
buffer
========================
*/
void  InputBuffer::SetActive(bool b)
{
    m_active = b;
}